package com.liang.config;

import com.liang.handler.*;
import com.liang.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * Created with IntelliJ IDEA.
 * User: XIAOLIANG
 * Date: 2021/5/12
 * Time: 10:30
 * Description: No Description
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) //全局
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


//    @Autowired
//    DAtaSou

    @Autowired
    AdminService adminService;  //实现了 UserDetailsService接口


//    @Override
//    public void configure(WebSecurity web) throws Exception {
//        //关闭springsecurity服务
//        web.ignoring().antMatchers("/**");
//    }

    @Bean
    public UsernamePasswordAuthenticationFilter usernamePasswordAuthenticationFilter() throws Exception {
        UsernamePasswordAuthenticationFilter filter = new MyUsernamePasswordAuthenticationFilter();
        //这里设置自带的AuthenticationManager，否则要自己写一个
        filter.setAuthenticationManager(authenticationManagerBean());
        //设置处理成功处理器
        filter.setAuthenticationSuccessHandler(new MyAuthenticationSuccessHandler()); // 设置 登录成功后的响应数据
        //设置过滤器拦截路径
        filter.setFilterProcessesUrl("/admin/login");                                // 登录的 请求地址,替换springsecurity 默认的登录路径
        return filter;
    }

    /**
     * 认证授权
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 基于角色的访问控制 ,拥有这两个角色 之一才能访问 menu/list 接口
        // .antMatchers("/menu/list").hasAnyRole("menuAdmin","admin")
        http.authorizeRequests()
                .antMatchers("/admin/login").permitAll()                      // 不需要 权限的请求

                .anyRequest()
                .authenticated()
                .and()
                    .formLogin()
                        .loginPage("http://localhost:8080/#/login")                  // 设置登录页面
//                        .loginProcessingUrl("/admin/login")
                        .successHandler(new MyAuthenticationSuccessHandler())       // 设置 登录成功后的响应数据
                        .failureHandler(new MyAuthenticationFailureHandler())       //设置 登录失败后的响应数据
                .and()
                    .exceptionHandling()
                        .authenticationEntryPoint(new MyAuthenticationEntryPoint())  //校验异常返回响应的数据
                        .accessDeniedHandler(new MyAccessDeniedHandler())               //权限校验未通过 相应的数据
                .and()
                    .logout()
                        .logoutUrl("/admin/logout")                                 //配置登出的地址  // 等同于 loginProcessingUrl("/user/login") /api/logout
                        .logoutSuccessHandler(new MyLogoutSuccessHandler())          //配置正常登出的响应数据
                .and()
                    .csrf()
                        .disable();                                                     // 解决跨域问题
    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(adminService)                                           // 配置userDetails的数据源，密码加密格式
                .passwordEncoder(new BCryptPasswordEncoder());
    }




    //    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth
//                .inMemoryAuthentication()
//                    .passwordEncoder(new BCryptPasswordEncoder())
//                    .withUser("user")
//                    .password(new BCryptPasswordEncoder().encode("user"))
//                    .roles("USER")
//                .and()
//                    .withUser("admin")
//                    .password(new BCryptPasswordEncoder().encode("admin"))
//                    .roles("ADMIN", "USER");
//
//    }


}
